/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package hirt;

import java.nio.ByteBuffer;
import java.util.Vector;
//import java.util.logging.Level;
//import java.util.logging.Logger;

/**
 * CreationActions are used to send all the possible information amount an item
 * across the network.  To reduce transmission sizes, all other actions just send the
 * item ID's in a transmissioin.  This action transforms all parts of the item into
 * a byte stream and sends it acroos the network
 * It is used by the server to add items to the game, such as when a responder arrives
 * @author zamille
 */
public class CreationAction extends Action
{
    /** The type of item that will be created.
     * possible value are the static members of Creation Action
     */
    public byte type;
    /** is this the first time the item was created.  Used with players*/
    public boolean firstTime;
    //public byte lanes;

    public static final byte ITEM = 1;
    public static final byte PLAYER = 2;
    public static final byte AUTOMOBILE = 3;
    public static final byte ITEM2D = 4;
    public static final byte LANES = 5;

    /**
     *
     */
    public CreationAction()
    {
        super();
        super.messageType = Message.CREATE_MESSAGE;
    }

    /**
     *
     * @param actor
     */
    public CreationAction(Item actor)
    {
        super( actor );

        setType();

        super.messageType = Message.CREATE_MESSAGE;
        firstTime = false;
    }

    /**
     *
     * @param actor
     * @param first
     */
    public CreationAction(Item actor, boolean first)
    {
        super(actor);
        setType();
        firstTime = first;
    }

    /**
     *
     * @param actor
     * @param itemType
     */
    public CreationAction(Item actor, byte itemType)
    {
        super(actor);
        type = itemType;
        firstTime = false;
        super.messageType = Message.CREATE_MESSAGE;
    }


    /**
     * Builds an Action from a byte stream, presumably created by an action across the network
     * this action should be identical to that one
     * @param bytes
     * @param items: Master Item List used to build the action
     */
    public CreationAction(ByteBuffer bytes, Vector<Item> items)
    {
        type = bytes.get(0);
        firstTime = ByteChanger.getBoolean(bytes,1);
        try {
            bytes = ByteChanger.truncate(bytes, 2);
        } catch (Exception ex) {

        }
        switch (type)
        {
            case ITEM:
                actor = new Item(bytes,items);
                break;
            case ITEM2D:
                actor = new Item2D(bytes,items);
                break;
            case AUTOMOBILE:
                actor = new Automobile(bytes,items);
                break;
            case PLAYER:
                actor = new Player(bytes, items);
                break;
            case LANES:
                actor = new Lane(bytes,items);
                break;
        }
        super.messageType = Message.CREATE_MESSAGE;
    }

    /**
     * Builds an Action from a save string, presumably read from a save
     * this action should be identical to the one saved in the file
     * @param save string
     * @param items: Master Item List used to build the action
     * @return what's left of the parem SaveString after this methods completes
     */
    CreationAction(String substring, Vector<Item> itemList) {
        fromSaveString(substring, itemList);
    }

    private void setType()
    {
        if (actor instanceof Automobile)
            type = AUTOMOBILE;
        else if (actor instanceof Player)
            type = PLAYER;
        else if (actor instanceof Lane)
            type = LANES;
        else if (actor instanceof Item2D)
            type = ITEM2D;
        else if (actor instanceof Item)
            type = ITEM;
        else
            type = 0;
    }

    /**
     * Returns a ByteBuffer representation of this Action
     * Used to send actions over the network
     * @return ByteBuffer
     */
    @Override
    public ByteBuffer toByte()
    {
        if (actor == null && type != LANES)
        {
            ByteBuffer buf = ByteBuffer.allocate(1);
            buf.put((byte)-1);
            return buf;
        }
        ByteBuffer buf = ByteBuffer.allocate(92);
        buf.put(type);
        buf.put(ByteChanger.booleanToByte(firstTime));
        //ByteBuffer bytes = actor.toByte();
        buf.put(actor.toByte().array());

        return buf;
    }

    /**
     * Returns a String representation of this Action
     * Used to save this action to a file
     * @return Save String
     */
    @Override
    public String toSaveString()
    {
        String text = "";
        text += type  + "\t";
        text += firstTime + "\t";
        text += getItemTypeInitial(actor) + "\t";
        text += actor.toSaveString()  + "\t";
        return text;
    }

    /**
     * Builds an Action from a save string, presumably read from a save
     * this action should be identical to the one saved in the file
     * @param save string
     * @param items: Master Item List used to build the action
     * @return what's left of the parem SaveString after this methods completes
     */
    @Override
    protected String fromSaveString(String text, Vector<Item> items)
    {
        String substring = ByteChanger.getNextValue(text);
        type = Byte.parseByte(substring);

        text = ByteChanger.incrementString(text);
        substring = ByteChanger.getNextValue(text);
        firstTime = Boolean.parseBoolean(substring);

        text = ByteChanger.incrementString(text);
        substring = ByteChanger.getNextValue(text);
        String itemType = substring;

        text = ByteChanger.incrementString(text);
        if (itemType.equals("A"))
            actor = new Automobile(text, items);
        else if (itemType.equals("L"))
            actor = new Lane (text, items);
        else if (itemType.equals("D"))
            actor = new Item2D(text,items);
        else if (itemType.equals("I"))
            actor = new Item(text, items);
        else
            actor = null;

        text = ByteChanger.incrementString(text);
        return text;
    }

    public static String getItemTypeInitial(Item item)
    {
        String save;
        if (item instanceof Automobile)
            save = "A";
        else if (item instanceof Lane)
            save = "L";
        else if (item instanceof Item2D)
            save = "D";
        else if (item instanceof Item)
            save = "I";
        else
            save = "";
        return save;
    }

}
